package com.test.sdk.core.filter;

import com.alibaba.dubbo.config.annotation.Reference;
import com.test.sdk.common.exception.SdkException;
import com.test.sdk.common.pojo.CP;
import com.test.sdk.common.pojo.OnlineUser;
import com.test.sdk.common.util.*;
import com.test.sdk.core.cache.CPCache;
import com.test.sdk.core.exception.SdkExceptionHandler;
import com.test.sdk.service.OnlineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author 徒有琴
 */
@WebFilter("*.html")
public class SignFilter implements Filter {

    private final long TEWNTY_MINUTES = 20 * 60 * 1000;
    private final long ONE_MINUTES = 1 * 60 * 1000;

    @Reference
    private OnlineService onlineService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private final String NEED_LOGIN_URL = "/user/.*";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //下午加统一异常处理  比如参数为空、签名错误等
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String signStr = SignUtil.getSignStr(request.getParameterMap());
        System.out.println(signStr);
        Integer cpId = RequestUtil.getInteger(request, "cpId");
        String mySign = null;
        try {
            if (cpId == null) {
                throw new SdkException(ErrorConstants.PARAM_ERROR);
            }
            CP cp = CPCache.getCPById(cpId);
            if (cp == null) {
                throw new SdkException(ErrorConstants.PARAM_ERROR);
            }
            String sign = RequestUtil.getString(request, "sign");
            if (sign == null) {
                throw new SdkException(ErrorConstants.PARAM_ERROR);
            }
            mySign = DigestUtils.getMD5(signStr + cp.getSecret());
            System.out.println(mySign);
            if (!mySign.equals(sign)) {
                throw new SdkException(ErrorConstants.SIGN_ERROR);
            }
            String path = request.getServletPath();
            if (path.matches(NEED_LOGIN_URL)) {
                checkLogin(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
            SdkExceptionHandler.handler(response, e);
            //调用异常处理器，统一把异常封装成json返回给客户端
            return;
        }
        filterChain.doFilter(request, response);

    }

    private void checkLogin(HttpServletRequest request, HttpServletResponse response) throws SdkException {
        String ticket = RequestUtil.getString(request, "ticket");
        if (ticket == null) {//需要登录的时候没有传票据
            throw new SdkException(ErrorConstants.PARAM_ERROR);
        }
        Date lastAct = TicketUtil.getTime(ticket);
        if (lastAct == null) {//ticket不合法，所以解析不出来
            throw new SdkException(ErrorConstants.PARAM_ERROR);
        }
        long diff = System.currentTimeMillis() - lastAct.getTime();
        if (diff > TEWNTY_MINUTES) {
            throw new SdkException(ErrorConstants.SESSION_TIMEOUT);
        }
        ticket = TicketUtil.decode(ticket);
        String userId = redisTemplate.opsForValue().get(ticket);
        if (userId == null) {
            throw new SdkException(ErrorConstants.SESSION_TIMEOUT);
        }
        if (diff > ONE_MINUTES) {
            //刷新有效期
            redisTemplate.opsForValue().set(ticket, userId, 20, TimeUnit.MINUTES);
            onlineService.updateLastAct(ticket);
        }
    }
}
